package com.tqjc.common.websocket.service.impl;

import com.alibaba.fastjson.JSON;
import com.tqjc.common.websocket.service.DeviceStatusInfoSendService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: 86195
 * @CreateTime: 2024-11-06  15:28
 * @Description: TODO
 * @Version: 1.0
 */
@Service
@Slf4j
public class DeviceStatusInfoSendServiceImpl implements DeviceStatusInfoSendService {


    @Resource
    private SimpMessageSendingOperations simpMessageSendingOperations;


    @Override
    @Scheduled(cron = "0/10 * *  * * ? ")
    @Async
    public void sendDeviceStatusInfo() {
        Map resMap = new HashMap(2);
        //1.检查PLC的状态
        //2号横移PLC
        boolean crane2PLCFlag = checkIPIntnetStatus("192.168.12.144");
        resMap.put("crane2PLCFlag",crane2PLCFlag);
        boolean crane4PLCFlag = checkIPIntnetStatus("192.168.12.176");
        resMap.put("crane4PLCFlag",crane4PLCFlag);

        boolean craneDJ3PLCFlag = checkIPIntnetStatus("192.168.12.128");
        resMap.put("craneDJ3PLCFlag",craneDJ3PLCFlag);

        boolean rollerNo2PLCFlag = checkIPIntnetStatus("192.168.16.101");
        resMap.put("rollerNo2PLCFlag",rollerNo2PLCFlag);

        boolean rollerNo45PLCFlag = checkIPIntnetStatus("192.168.16.112");
        resMap.put("rollerNo45PLCFlag",rollerNo45PLCFlag);

        boolean operateNo345PLCFlag = checkIPIntnetStatus("192.168.12.217");
        resMap.put("operateNo345PLCFlag",operateNo345PLCFlag);


        boolean crane3PLCFlag = checkIPIntnetStatus("192.168.12.160");
        resMap.put("crane3PLCFlag",crane3PLCFlag);

        boolean crane5PLCFlag = checkIPIntnetStatus("192.168.12.193");
        resMap.put("crane5PLCFlag",crane5PLCFlag);

        boolean craneDJ2PLCFlag = checkIPIntnetStatus("192.168.12.112");
        resMap.put("craneDJ2PLCFlag",craneDJ2PLCFlag);


        boolean rollerNo3PLCFlag = checkIPIntnetStatus("192.168.16.102");
        resMap.put("rollerNo3PLCFlag",rollerNo3PLCFlag);

        boolean rollerDJPLCFlag = checkIPIntnetStatus("192.168.8.156");
        resMap.put("rollerDJPLCFlag",rollerDJPLCFlag);


        boolean operateNo2PLCFlag = checkIPIntnetStatus("192.168.12.216");
        resMap.put("operateNo2PLCFlag",operateNo2PLCFlag);

        //2.检查数据库状态   一级数据库的状态用ping指令
        boolean upstreamDataSourceFlag = checkIPIntnetStatus("192.168.4.248");
        resMap.put("upstreamDataSourceFlag",upstreamDataSourceFlag);

        boolean dataSourceFlag = checkPortStatus(3306);
        resMap.put("dataSourceFlag",dataSourceFlag);

        //3.采数平台状态
        boolean dataCollectFlag = checkPortStatus(80);
        resMap.put("dataCollectFlag",dataCollectFlag);

        simpMessageSendingOperations.convertAndSend("/topic/allDeviceData", JSON.toJSONString(resMap));
    }

    /**
     * 判断IP连接是否正常
     * @param ip
     * @return   true:网络正常  false:网络异常
     */
    private boolean checkIPIntnetStatus(String ip){
        try {
            InetAddress inetAddress = InetAddress.getByName(ip);
            boolean isReachable = inetAddress.isReachable(5000);  // 5秒超时
            if (isReachable) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("外部设备检查异常,ip:{}" ,ip, e);
            return false;
        }
    }

    /**
     *
     * @param portNo
     * @return   true:端口被占用，说明该端口已启动，关联系统可用    false:端口没有被占用，说明该端口没启动，关联系统不可用
     */
    private boolean checkPortStatus(int portNo){
        try (ServerSocket serverSocket = new ServerSocket(portNo)) {
            // 如果能够成功绑定端口，表示端口没有被占用
            log.info("端口：{},没有被占用，关联系统异常",portNo);
            return false;
        } catch (IOException e) {
            // 如果抛出异常，表示端口已被占用
            return true;
        }
    }
}
